import _ from 'lodash'
import CustomVanInput from '@/components/Form/CustomVanInput'
import CustomVanSelect from '@/components/Form/CustomVanSelect'
import CustomVanTextarea from '@/components/Form/CustomVanTextarea'
import CustomVanRadio from '@/components/Form/CustomVanRadio'
import CustomVanCheckBox from '@/components/Form/CustomVanCheckBox'
import CustomDatetimePicker from '@/components/Form/CustomDatetimePicker'
import CustomVanArea from '@/components/Form/CustomVanArea'
import CustomVanTable from '@/components/Form/CustomVanTable'
import CustomVanUploader from '@/components/Form/CustomVanUploader'
import CustomVanNumber from '@/components/Form/CustomVanNumber'

// layout
import FieldGroup from '@/components/Form/FieldGroup'
import FieldExplain from '@/components/Form/Layout/FieldExplain'

import {
  inputType,
  fileType,
  datetimeType,
  radioType,
  selectType,
  checkboxType,
  textareaType,
  addressType,
  tableType,
  layoutType,
  groupType,
  numberType,
} from '@/components/Form/fieldType'

export default {
  props: {
    formGenerator: {
      type: Object,
      default: () => ({
        name: '',
        generator: [],
      }),
    },
    defaultProps: {
      type: Object,
      default: () => ({
        label: 'field_type',
        choice: 'choice',
      }),
    },
    defaultSelectProps: {
      type: Object,
      default: () => ({
        choice: 'choice',
        data: {
          label: 'title',
          value: 'id',
          has_fill: 'has_fill',
        },
      }),
    },
    defaultCheckboxProps: {
      type: Object,
      default: () => ({
        choice: 'choice',
        data: {
          fill: 'fill',
          label: 'title',
          value: 'id',
          has_fill: 'setting.has_fill',
        },
      }),
    },
    defaultRadioProps: {
      type: Object,
      default: () => ({
        choice: 'choice',
        data: {
          label: 'title',
          value: 'id',
          has_fill: 'setting.has_fill',
        },
      }),
    },
    collectInputProps: {
      type: Object,
      default: () => ({
        type: 'value',
      }),
    },
    collectSelectProps: {
      type: Object,
      default: () => ({
        type: 'choice',
      }),
    },
    collectChoiceProps: {
      type: Object,
      default: () => ({
        type: 'choice',
        fill: 'fill',
      }),
    },
    collectCheckProps: {
      type: Object,
      default: () => ({
        type: 'choice',
        fill: 'fill',
      }),
    },
    collectTableProps: {
      type: Object,
      default: () => ({
        type: 'table_value',
      }),
    },
    collectUploaderProps: {
      type: Object,
      default: () => ({
        type: 'files',
      }),
    },
  },

  methods: {
    generatorComp (generator) {
      if (!generator.length) return false
      // console.log(generator, 'g--r');
      const fcomp = this.formComponent

      // fields
      const { file, image } = fileType
      const { input, sys } = inputType
      const { number } = numberType
      const { textarea } = textareaType
      const { radio } = radioType
      const { checkbox } = checkboxType
      const { select } = selectType
      const { address } = addressType
      const { datetime } = datetimeType
      const { table } = tableType

      // layout
      const { group } = groupType
      const { ortc, explain } = layoutType

      _.forEach(generator, (gener) => {
        const fields = gener
        const { type, init_value = {}, field_value } = fields
        fields.value = init_value.label || '' // value
        fields.field_value = field_value || []
        let compProp = null // comp

        switch (type) {
          case input.type: // input
          case sys.type: // sys
            compProp = this.createInput({ fields })
            break

          case number.type:
            compProp = this.createNumber({ fields })
            break

          case table.type: // table
            compProp = this.createTable({ fields })
            break

          case textarea.type: // textarea
            compProp = this.createTextarea({ fields })
            break

          case file.type:
          case image.type: // image
            compProp = this.createFile({ fields })
            break

          case address.type: // address
            compProp = this.createAddress({ fields })
            break

          case datetime.type: // datetime
            compProp = this.createDatetime({ fields })
            break

          case radio.type: // radio
            fields.value = init_value
            compProp = this.createRadio({ fields })
            break

          case checkbox.type: // checkbox
            console.log(checkbox, 'checkbox')
            compProp = this.createCheckbox({ fields })
            break

          case select.type: // select
            compProp = this.createSelect({ fields })
            break

          case group.type: // group
            compProp = this.createGroup({ fields })
            break

          case ortc.type: // ortc
            compProp = this.createOrtc({ fields })
            break

          case explain.type: // explain
            compProp = this.createExplain({ fields })
            break

          default: // error
            // throw new Error('error');
            break
        }

        // not compProp
        if (compProp) {
          const constru = compProp.constructor
          switch (constru) {
            case Array: // 多个组件
              fcomp.push(..._.map(compProp,
                ({ comp, prop }) => ({ component: comp, prop })))
              break

            default: // 单个组件
              {
                const { comp, prop } = compProp
                fcomp.push({
                  component: comp,
                  prop,
                })
              }
              break
          }
        }
      })
      return { fcomp }
    },

    // 获取表单数据
    getFormValue () {},

    // 获取表单label
    getFieldLabel ({ fv, fields }) {
      const { title, field_type } = fields
      return `${(title || field_type)}（${fv?.user || '无'}）`
    },

    // create number
    createNumber ({ fields }, comp = CustomVanNumber) {
      const {
        field_value, value, setting, can_do,
      } = fields
      const { decimal_length, read_only, thousand } = setting
      fields.collectProps = this.collectInputProps
      const { number } = numberType
      const { getProp } = number

      // can_do
      const canDo = (!can_do || read_only)

      // getValue
      function getFieldValue (fv, fs = fields) {
        const val = fv?.field_detail?.value || value
        const num = Number(val)

        // 千分位
        const formatData = (num1) => {
          const reg = /(\d)(?=(\d{3})+\.)/g
          num1 = num1.toString()
          if (!num1.includes('.')) {
            num1 += '.'
          }
          return num1.replace(reg, ($0, $1) => (`${$1},`))
            .replace(/\.$/, '')
        }

        // 转换
        const format = (nm, fixed = 0) => {
          let n = nm.toFixed(fixed)
          if (thousand) {
            n = formatData(n)
          }
          return n
        }

        const prop = getProp({
          fields: {
            ...fs,
            pattern: canDo ? 'text' : 'number',
            value: Number.isNaN(num) || !canDo ? val : format(num, decimal_length),
          },
        })
        return { prop, comp }
      }

      switch (field_value.length) {
        // 无人填写
        case 0:
        case 1:
        {
          const [fv = {}] = field_value
          return getFieldValue(fv)
        }

        // 单人或者多人填写
        default:
        {
          return _.map(field_value, (fv) => getFieldValue(fv, {
            ...fields,
            title: this.getFieldLabel({ fv, fields }),
          }))
        }
      }
    },

    // create input
    createInput ({ fields }) {
      const { field_value, value } = fields
      fields.collectProps = this.collectInputProps
      const comp = CustomVanInput
      const { input } = inputType
      const { getProp: inputProp } = input

      // getValue
      function getFieldValue (fv, fs = fields) {
        const val = fv?.field_detail?.value || value
        const prop = inputProp({
          fields: {
            ...fs,
            value: val,
          },
        })
        return { prop, comp }
      }

      switch (field_value.length) {
        // 无人填写
        case 0:
        case 1:
        {
          const [fv = {}] = field_value
          return getFieldValue(fv)
        }

        // 单人或者多人填写
        default:
        {
          return _.map(field_value, (fv) => getFieldValue(fv, {
            ...fields,
            title: this.getFieldLabel({ fv, fields }),
          }))
        }
      }
    },

    // create textarea
    createTextarea ({ fields }) {
      const { field_value, value } = fields
      const comp = CustomVanTextarea
      fields.collectProps = this.collectInputProps

      const { textarea } = textareaType
      const { getProp: textareaProp } = textarea

      // getValue
      function getFieldValue (fv, fs = fields) {
        const val = fv?.field_detail?.value || value
        const prop = textareaProp({
          fields: {
            ...fs,
            value: val,
          },
        })
        return { prop, comp }
      }

      switch (field_value.length) {
        // 无人填写
        case 0:
        case 1:
        {
          const [fv = {}] = field_value
          return getFieldValue(fv)
        }

        // 单人或者多人填写
        default:
        {
          return _.map(field_value, (fv) => getFieldValue(fv, {
            ...fields,
            title: this.getFieldLabel({ fv, fields }),
          }))
        }
      }
    },

    // create address -sssss
    createAddress ({ fields }) {
      const { address } = addressType
      const { getProp: addressProp } = address

      const prop = addressProp({ fields })
      const comp = CustomVanArea

      return { prop, comp }
    },

    // create datetime
    createDatetime ({ fields }) {
      const { field_value, value } = fields
      fields.collectProps = this.collectInputProps
      console.log(field_value, 'f--c')

      const { datetime } = datetimeType
      const { getProp: datetimeProp } = datetime
      const comp = CustomDatetimePicker

      // getValue
      function getFieldValue (fv, fs = fields) {
        const val = fv?.field_detail?.value || value
        const prop = datetimeProp({ fields: { ...fs, value: val } })
        return { prop, comp }
      }

      switch (field_value.length) {
        // 无人填写
        case 0:
        case 1:
        {
          const [fv = {}] = field_value
          return getFieldValue(fv)
        }

        // 单人或者多人填写
        default:
        {
          return _.map(field_value, (fv) => getFieldValue(fv, {
            ...fields,
            title: this.getFieldLabel({ fv, fields }),
          }))
        }
      }
    },

    // create radio
    createRadio ({ fields }) {
      const comp = CustomVanRadio
      const { type } = this.collectChoiceProps
      const { field_value, value } = fields
      fields.defaultProps = this.defaultRadioProps
      fields.collectProps = this.collectChoiceProps
      const { radio } = radioType
      const { getProp: radioProp } = radio

      // getValue
      function getFieldValue (fv, fs = fields) {
        const { choice, fill } = fv?.field_detail || { choice: value.value, fill: '' }
        const prop = radioProp({
          fields: {
            ...fs,
            value: {
              [type]: choice, fill,
            },
          },
        })
        return { prop, comp }
      }

      switch (field_value.length) {
        // 无人填写
        case 0:
        case 1:
        {
          const [fv = {}] = field_value
          return getFieldValue(fv)
        }

        // 单人或者多人填写
        default:
        {
          return _.map(field_value, (fv) => getFieldValue(fv, {
            ...fields,
            title: this.getFieldLabel({ fv, fields }),
          }))
        }
      }
    },

    // create checkbox
    createCheckbox ({ fields }) {
      const comp = CustomVanCheckBox
      const { field_value } = fields
      fields.defaultProps = this.defaultCheckboxProps
      fields.collectProps = this.collectCheckProps

      const { checkbox } = checkboxType
      const { getProp: checkboxProp } = checkbox

      // getValue
      function getFieldValue (fv, fs = fields) {
        const { check_value = [] } = fv?.field_detail || {}

        const prop = checkboxProp({
          fields: {
            ...fs,
            value: _.map(check_value, ({ choice }) => (choice)),
            checkValue: check_value,
          },
        })
        return { prop, comp }
      }

      switch (field_value.length) {
        // 无人填写
        case 0:
        case 1:
        {
          const [fv = {}] = field_value
          return getFieldValue(fv)
        }

        // 多人填写
        default:
        {
          return _.map(field_value, (fv) => getFieldValue(fv, {
            ...fields,
            title: this.getFieldLabel({ fv, fields }),
          }))
        }
      }
    },

    // 下拉选择
    createSelect ({ fields }) {
      const comp = CustomVanSelect
      const { field_value, value } = fields
      fields.defaultProps = this.defaultSelectProps
      fields.collectProps = this.collectSelectProps
      const { select } = selectType
      const { getProp: selectProp } = select

      // getValue
      function getFieldValue (fv, fs = fields) {
        const { ref_value = '' } = fv?.field_detail || {}
        const prop = selectProp({
          fields: {
            ...fs,
            value: ref_value || value,
          },
        })
        return { prop, comp }
      }

      switch (field_value.length) {
        // 无人填写
        case 0:
        case 1:
        {
          const [fv = {}] = field_value
          return getFieldValue(fv)
        }

        // 多人填写
        default:
        {
          return _.map(field_value, (fv) => getFieldValue(fv, {
            ...fields,
            title: this.getFieldLabel({ fv, fields }),
          }))
        }
      }
    },

    // create gronp
    createGroup ({ fields }) {
      console.log(fields, 'groups')
      const { group } = groupType
      const { getProp: groupProp } = group

      const prop = groupProp({ fields })
      const comp = FieldGroup
      return { prop, comp }
    },

    createExplain ({ fields }) {
      const { explain } = layoutType
      const { getProp } = explain

      const prop = getProp({ fields })
      const comp = FieldExplain
      return { prop, comp }
    },

    // create table
    createTable ({ fields }) {
      fields.collectProps = this.collectTableProps

      const { table: fieldTable } = fields
      const { table } = tableType
      const { getProp: tableProp } = table
      if (fieldTable) {
        const prop = tableProp({
          fields: {
            ...fields,
            value: fieldTable?.row,
          },
        })
        const comp = CustomVanTable

        return { prop, comp }
      }
    },

    // create ortc
    createOrtc ({ fields }) {
      this.generatorComp(fields.fields)
    },

    // create file
    createFile ({ fields }) {
      const comp = CustomVanUploader
      const { image } = fileType
      const { field_value } = fields
      const { getProp: fileProp } = image
      fields.collectProps = this.collectUploaderProps

      // getValue
      function getFieldValue (fv, fs = fields) {
        const val = fv?.field_detail?.files || []
        const prop = fileProp({ fields: { ...fs, value: val } })
        return { prop, comp }
      }

      switch (field_value.length) {
        // 无人填写
        case 0:
        case 1:
        {
          const [fv = {}] = field_value
          return getFieldValue(fv)
        }

        // 单人或者多人填写
        default:
        {
          return _.map(field_value, (fv) => getFieldValue(fv, {
            ...fields,
            title: this.getFieldLabel({ fv, fields }),
          }))
        }
      }
    },
  },
}
